﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../data_struct/head.h"
#include "../macro/head.h"
#include "des_impl.h"
#include "mgr.h"

namespace xos_encrypt
{
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static des_impl::POOL * pool_ptr = 0;

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    des_impl::des_impl()
    {
        init_data();
    }

    des_impl::~des_impl()
    {}

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // public method

    int des_impl::get_addr( POOL *** pppPool, LIST *** pppList )
    {
        int ret = 0;
        if( pppPool )
        {
            *pppPool = &pool_ptr;
        }
        if( pppList )
        {
            *pppList = 0;
        }
        return ret;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int des_impl::init_data()
    {
        int ret = 0;

        mgr::crt()->memset( m_sz3DesKey, 0, sizeof( m_sz3DesKey ) );
        m_n3DesKeyLen = 0;

        m_pMisc = 0;

        return ret;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int des_impl::init()
    {
        int ret = 0;

        if( 0 == ret )
        {
            ret = mgr::common()->create( xos_common::OBJ_MISC, (void**)&m_pMisc );
        }

        return ret;
    }

    int des_impl::term()
    {
        int ret = 0;

        xos_stl::release_interface( m_pMisc );
        init_data();

        return ret;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    // other : 返回长度
    //    -1 : 失败
    int des_impl::encode( char * lpszOutBuf, const char * lpszInBuf, int nInLen )
    {
        int ret = 0;
        ret = m_pMisc->DoDES( lpszOutBuf, lpszInBuf, nInLen, m_sz3DesKey, m_n3DesKeyLen, true );
        return ret;
    }

    // other : 返回长度
    //    -1 : 失败
    int des_impl::decode( char * lpszOutBuf, const char * lpszInBuf, int nInLen )
    {
        int ret = 0;
        ret = m_pMisc->DoDES( lpszOutBuf, lpszInBuf, nInLen, m_sz3DesKey, m_n3DesKeyLen, false );
        return ret;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    // encode with buf
    int des_impl::encode( xos_box::i_buf * pOutBuf, xos_box::i_buf * pInBuf )
    {
        int ret = 0;

        int nOutLen = 0;
        int nInLen = 0;
        char * pIn = pInBuf->get_data( 0, 0, &nInLen );
        char * pOut = pOutBuf->get_data( 0, 0, 0 );

        nOutLen = encode( pOut, pIn, nInLen );

        if( nOutLen > 0 )
        {
            pOutBuf->set_len( nOutLen );
            ret = nOutLen;
        }
        else
        {
            ret = -1;
        }

        return ret;
    }

    int des_impl::decode( xos_box::i_buf * pOutBuf, xos_box::i_buf * pInBuf )
    {
        int ret = 0;

        int nOutLen = 0;
        int nInLen = 0;
        char * pIn = pInBuf->get_data( 0, 0, &nInLen );
        char * pOut = pOutBuf->get_data( 0, 0, 0 );

        nOutLen = decode( pOut, pIn, nInLen );

        if( nOutLen > 0 )
        {
            pOutBuf->set_len( nOutLen );
            ret = nOutLen;
        }
        else
        {
            ret = -1;
        }

        return ret;
    }

    // encode with list
    int des_impl::encode( xos_box::i_list * pOutList, xos_box::i_list * pInList )
    {
        int ret = 0;

        xos_box::i_buf * pIn = 0;

        while( ( 0 == ret ) && ( pIn = ( xos_box::i_buf * )pInList->front( 0 ) ) )
        {
            xos_box::i_buf * pOut = mgr::buf();
            int len = encode( pOut, pIn );
            if( len > 0 )
            {
                xos_stl::release_interface( pIn );
                pOutList->push_back( pOut );
                pInList->pop_front();
                pOut = 0;
            }
            else
            {
                ret = 1;
            }
            xos_stl::release_interface( pOut );
        }

        return ret;
    }

    int des_impl::decode( xos_box::i_list * pOutList, xos_box::i_list * pInList )
    {
        int ret = 0;

        xos_box::i_buf * pIn = 0;

        while( ( 0 == ret ) && ( pIn = ( xos_box::i_buf * )pInList->front( 0 ) ) )
        {
            xos_box::i_buf * pOut = mgr::buf();
            int len = decode( pOut, pIn );
            if( len > 0 )
            {
                xos_stl::release_interface( pIn );
                pOutList->push_back( pOut );
                pInList->pop_front();
                pOut = 0;
            }
            else
            {
                ret = 1;
            }
            xos_stl::release_interface( pOut );
        }

        return ret;
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    // 3des方法
    int des_impl::set_3des_key( const char * lpszKey, int nKeyLen )
    {
        int ret = 0;
        mgr::crt()->memcpy( m_sz3DesKey, lpszKey, nKeyLen );
        m_n3DesKeyLen = nKeyLen;
        return ret;
    }

} // xos_encrypt
